package com.baikeyang.common.util;

import cn.hutool.db.nosql.redis.RedisDS;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;

import java.io.IOException;
import java.util.*;

/**
 * Redis工具类
 * @author BaiKeyang
 */
public class RedisUtil {

    private static final Logger logger = LogManager.getLogger(RedisUtil.class);

    /**
     * 获取Jedis实例
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            return RedisDS.create().getJedis();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 释放jedis资源
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * 根据key设置字符串值
     * @param key
     * @param value
     * @return
     * @throws Exception
     */
    public static void setString(String key, String value) throws Exception {

        Jedis jedis = getJedis();

        if (jedis == null) {
            throw new Exception("getJedis error!");
        }

        //result = jedis.sadd(key, value);
        jedis.set(key, value);

        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                logger.error("returnResource error!");
                e.printStackTrace();
            }
        }

    }

    /**
     * 根据key获取字符串值
     * @param key
     * @return
     * @throws Exception
     */
    public static String getString(String key) throws Exception {
        String result = "";

        Jedis jedis = getJedis();

        if (jedis == null) {
            throw new Exception("getJedis error!");
        }

        result = jedis.get(key);

        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }

        return result;
    }

    public static List<String> getStrings(List<String> keys) throws Exception {
        List<String> result = new ArrayList<String>();

        Jedis jedis = getJedis();

        if (jedis == null) {
            throw new Exception("getJedis error!");
        }
        for(String key : keys){
            result.add(jedis.get(key));
        }
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
        return result;
    }

    /**
     * 模糊匹配redis中key的集合
     *
     * @param pattern
     * @return 返回匹配到的所有key的集合
     * @throws Exception
     */
    public static Set<String> getKeys(String pattern) throws Exception {
        Set<String> keys = new HashSet<String>();

        Jedis jedis = getJedis();
        if (jedis == null) {
            throw new Exception("getJedis error!");
        }

        keys = jedis.keys(pattern);

        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
        return keys;
    }

    /**
     * 批量存入redis
     * @param keys
     * @param values
     * @throws Exception
     */
    public static void setBytes(List<byte[]> keys, List<byte[]> values)
            throws Exception {
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        }

        byte[] key = new byte[30];
        byte[] value = new byte[30];
        //遍历参数list
        for (int i = 0; i < keys.size(); i++) {
            //获取每一个key value
            key = keys.get(i);
            value = values.get(i);
            jedis.set(key, value);
        }

        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }

    }

    /**
     * 批量存入redis
     * @param keys
     * @param values
     * @throws Exception
     */
    public static void setStrings(List<String> keys, List<String> values)
            throws Exception {
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        }

        String key = "";
        String value = "";
        logger.debug("本次更新数据："+keys.size());
        Pipeline p = jedis.pipelined();
        //遍历参数list
        for (int i = 0; i < keys.size(); i++) {
            key = keys.get(i);
            value = values.get(i);
            p.set(key, value);
        }
        p.sync();
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }

    }

    /**
     * 根据key值获取byte[]
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] getBytes(String key) throws Exception {
        byte[] bytesVal = null;
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        } else if (key == null || key.trim().equals("")) {
            logger.error("key error!");
        }

        bytesVal = jedis.get(key.getBytes());

        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }

        return bytesVal;
    }


    /**
     * 存入redis
     * @param key
     * @param field
     * @param value
     * @throws Exception
     */
    public static void setHSet(String key, String field, String value)
            throws Exception {
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        }
        jedis.hset(key, field, value);
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
    }

    /**
     * 存入redis
     * @param key
     * @param fields
     * @param values
     * @throws Exception
     */
    public static void setHSet(String key, List<String> fields, List<String> values)
            throws Exception {
        Jedis jedis = getJedis();
        if (jedis == null) {
            logger.error("getJedis error!");
        }
        String field = "", value = "";
        // 遍历参数list,使用pipeline hmset
        Pipeline p = jedis.pipelined();
        Map<String, String> data = new HashMap<String, String>();
        for (int i = 0; i < fields.size(); i++) {
            data.clear();
            //获取每一个key value
            field = fields.get(i);
            value = values.get(i);
            data.put(field, value);
            p.hmset(key, data);
        }
        p.sync();
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
    }

    public static String hgetValue(String key, String field)
            throws Exception {
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        }
        String value = jedis.hget(key, field);
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
        return value;
    }

    public static List<String> hgetKey(String key, String... fields)
            throws Exception {
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        }
        List<String> list = jedis.hmget(key, fields);
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
        return list;
    }

    /**
     * 获取redis hgetKeys
     * @param key
     * @throws Exception
     */
    public static Map<String, String> hgetKeys(String key)
            throws Exception {
        Jedis jedis = getJedis();

        if (jedis == null) {
            logger.error("getJedis error!");
        }
        Map<String, String> map = jedis.hgetAll(key);
        if (jedis != null) {
            try {
                returnResource(jedis);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("returnResource error!");
            }
        }
        return map;
    }

    public static Long del(String... keys) {
        Jedis jedis = getJedis();
        return jedis.del(keys);
    }

    public static Long hdel(String key, String... fields) {
        Jedis jedis = getJedis();
        return jedis.hdel(key, fields);
    }

    public static void main(String[] args) {
        try {
            Jedis jedis = RedisUtil.getJedis();
            System.out.println(jedis);
            RedisUtil.setString("QQ", "TTT");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
